home *** CD-ROM | disk | FTP | other *** search
/ Pascal Super Library / Pascal Super Library (CW International)(1997).bin / SHELLS / SHELL / SHELSORT.ASM next >
Assembly Source File  |  1986-08-30  |  5KB  |  112 lines

  1. ;Assemble to SHELL.EXE, then use EXE2BIN to convert to .COM file
  2. ;declare in TURBO PASCAL source file as below
  3.  
  4. ;procedure shellsort(len,field,entries,size:integer; var struc);
  5.  
  6. ;len     = the length of the key (sort) field
  7. ;field   = offset of the field within the record (add 1 for string fields)
  8. ;entries = number of records in the array
  9. ;struc   = the declared name of the array
  10.  
  11. code         segment
  12.              assume cs:code
  13.  
  14. ;use equates to keep things straight
  15.  
  16. STRUC        equ [bp+4]
  17. SIZE         equ [bp+8]
  18. ENTRIES      equ [bp+10]
  19. FIELD        equ [bp+12]
  20. LEN          equ [bp+14]
  21. N            equ [bp-2]
  22. JUMP         equ [bp-4]
  23. N_JUMP       equ [bp-6]
  24.  
  25.  
  26. sort:        push bp                ;save bp
  27.              mov bp,sp              ;reference the stack with bp
  28.              sub sp,10              ;make some working space for local vars
  29.              push ds                ;preserve ds
  30.              push es                ;and es as well (although not necessary)
  31.              les di,STRUC           ;load es with struc seg - di with struc ofs
  32.              lds si,STRUC           ;same with ds
  33.              jmp sortem             ;goto main body
  34.  
  35. compare:     push si                ;save the pointers
  36.              push di
  37.              push cx                ;save the counter
  38.              mov cx,LEN             ;no of bytes to scan
  39.              add si,word ptr FIELD  ;bump si by key field length
  40.              add di,word ptr FIELD  ;bump di by key field length
  41.              repz cmpsb             ;compare em!
  42.              pop cx                 ;flag will be set accordingly
  43.              pop di                 ;restore regs
  44.              pop si
  45.              ret                    ;and return
  46.  
  47. swap:        push si                ;save the pointers
  48.              push di
  49.              push cx                ;save the counter
  50.              push ax                ;will use ax, so save it
  51.              cld                    ;move is forward
  52. again1:      mov al,byte ptr[di]    ;save one byte
  53.              movsb                  ;move one bye
  54.              mov byte ptr es:[si-1],al ;move saved byte
  55.              loop again1            ;continue for length of record
  56.              pop ax                 ;restore regs
  57.              pop cx
  58.              pop di
  59.              pop si
  60.              ret                    ;and return
  61.  
  62. sortem:      mov cx,ENTRIES         ;no. of entries
  63.              mov dx,SIZE            ;size of record
  64.              mov N,cx               ;store N
  65.              mov JUMP,cx            ;store JUMP (JUMP = N)
  66.              dec word ptr N         ;N = N - 1
  67.  
  68. loop1:       cmp word ptr JUMP,1    ;is JUMP > 1?
  69.              jbe exit               ;no - sort complete
  70.              shr word ptr JUMP,1    ;JUMP = JUMP DIV 2
  71.  
  72. loop2:       mov bl,1               ;set DONE = TRUE
  73.              mov ax,N               ;get N
  74.              sub ax,word ptr JUMP   ;compute N - JUMP
  75.              mov N_JUMP,ax          ;store N - JUMP
  76.              mov cx,0
  77.                                     ;for J = 1 to N - JUMP DO
  78. loop3:       push si                ;save pointer to record
  79.              push di                ;save pointer to record
  80.              mov ax,SIZE            ;get rec size
  81.              mul cx                 ;multipy by J
  82.              add si,ax              ;j = si, so a[j] = a[si]
  83.              mov ax,SIZE            ;get rec size
  84.              mul word ptr JUMP      ;multiply by JUMP
  85.              add ax,si              ;offset from si (j)
  86.              mov di,ax              ;i = di, so a[i] = a[di]
  87.              call compare           ;compare fields
  88.              jbe no_swap            ;no swap
  89.              push cx                ;save loop counter
  90.              mov cx,SIZE            ;SWAP needs size of record
  91.              call swap              ;do it!
  92.              pop cx                 ;restore loop counter
  93.              mov bl,0               ;set DONE = FALSE
  94. no_swap:     cmp cx,word ptr N_JUMP ;is cx = N - JUMP?
  95.              pop di                 ;restore pointer
  96.              pop si                 ;restore pointer
  97.              inc cx                 ;bump the counter
  98.              jb loop3               ;if cycle not complete, go again
  99.              cmp bl,0               ;is DONE = FALSE
  100.              je loop2               ;no, another cycle
  101.              jmp loop1              ;keep going until sort is complete
  102. exit:        pop es                 ;restore es reg
  103.              pop ds                 ;restore ds reg
  104.              mov sp,bp              ;restore original sp
  105.              pop bp                 ;restore original bp
  106.              ret 12                 ;clean up stack for TURBO
  107. code         ends
  108.              end sort
  109.  
  110.  
  111.  
  112.